package cc.vv.party.gen

import com.baomidou.mybatisplus.generator.AutoGenerator
import com.baomidou.mybatisplus.generator.InjectionConfig
import com.baomidou.mybatisplus.generator.config.*
import com.baomidou.mybatisplus.generator.config.po.TableInfo
import com.baomidou.mybatisplus.generator.config.rules.DbType
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy
import commonx.core.content.isNotNullOrEmpty
import commonx.core.json.jsonPath
import commonx.core.json.toJSONObject
import java.util.*

/**
 * @version 1.0.0
 * @author: Gyb
 * @date 2018-10-11
 * @description
 **/
class CodeGen {

    /** 代码默认作者作者  */
    private val AUTHOR = "Gyb"

    //数据库地址
    //private static final String DB_NAME = "life_health";

    /** 设置代码生成地址  */
    private var outDir: String? = null

    /** 设置代码编辑作者  */
    private var zuozhe: String? = null

    /**
     * 设置生成文件输出地址
     * @param outDir 文件生成地址
     * @return
     */
    fun setOutDir(outDir: String?): CodeGen {
        if (outDir.isNotNullOrEmpty()) {
            this.outDir = outDir
        } else {
            val projectPath = System.getProperty("user.dir")
//            this.outDir = "$projectPath/src/main/kotlin/cc/"
            this.outDir = "$projectPath/gen/"
        }
        return this
    }

    /**
     * 设置文件编辑作者
     * @param author 作者英文名称
     * @return
     */
    fun setAuthor(author: String): CodeGen {
        if (author.isNotNullOrEmpty()) {
            this.zuozhe = author
        } else {
            this.zuozhe = AUTHOR
        }
        return this
    }

    /**
     * 设置全局配置
     * @return
     */
    fun getGlobalConfig(): GlobalConfig {
        val globalConfig = GlobalConfig()
        globalConfig.isActiveRecord = true
        globalConfig.outputDir = this.outDir
        globalConfig.isFileOverride = true// 是否覆盖文件
        globalConfig.isActiveRecord = true// 开启 activeRecord 模式
        globalConfig.isEnableCache = false// XML 二级缓存
        globalConfig.isBaseResultMap = true// XML ResultMap
        globalConfig.isBaseColumnList = true// XML columList
        globalConfig.author = this.zuozhe
        globalConfig.serviceName = "%sService"
        globalConfig.isKotlin = true
        globalConfig.controllerName = "%sApi"
        globalConfig.mapperName = "%sMapper"
        globalConfig.isOpen = false
        return globalConfig
    }

    /**
     * 设置数据源配置
     * @param dbType 数据库类型
     * @param driverName 驱动包名称
     * @param dbUserName  数据库用户名
     * @param dbUserPwd 数据库密码
     * @param url 数据库访问链接
     * @return
     */
    fun getDataSourceConfig(
        dbType: DbType,
        driverName: String,
        dbUserName: String,
        dbUserPwd: String,
        url: String
    ): DataSourceConfig {
        val dsc = DataSourceConfig()
        dsc.dbType = dbType
        dsc.driverName = driverName
        dsc.username = dbUserName
        dsc.password = dbUserPwd
        dsc.url = url
        return dsc
    }

    /**
     * 项目继承策略
     * @param tablePrefix 表前缀
     * @param includeTable 需要生成的表
     * @param excludeTable 需要排除的表
     * @return
     *
     *  生成表和排除表二选其一即可
     */
    fun getStrategyConfig(
        tablePrefix: Array<String>,
        includeTable: Array<String>?,
        excludeTable: Array<String>?
    ): StrategyConfig {
        // 策略配置
        val strategy = StrategyConfig()
        strategy.isRestControllerStyle = true
        strategy.entityTableFieldAnnotationEnable(true)
        strategy.setTablePrefix(*tablePrefix)// 此处可以修改为您的表前缀
        strategy.naming = NamingStrategy.underline_to_camel// 表名生成策略
        strategy.isControllerMappingHyphenStyle = true
        if (includeTable != null) {
            strategy.setInclude(*includeTable) // 需要生成的表
        }

        if (excludeTable != null) {
            strategy.setExclude(*excludeTable) // 排除生成的表
        }

        // 自定义实体父类
        strategy.superEntityClass = "cc.vv.party.common.base.BaseModel"

        // 自定义实体，公共字段
        strategy.setSuperEntityColumns("id", "create_time", "update_time", "logic_delete", "create_user")

        // 自定义 api 父类
        strategy.superControllerClass = "cc.vv.party.common.base.BaseController"

        strategy.superServiceClass = "cc.vv.party.common.base.BaseService"

        strategy.superServiceImplClass = "cc.vv.party.common.base.BaseServiceImpl"

        return strategy
    }

    /**
     * 生成包设置
     * @param moduleName 模块名称
     * @param parentPackageName 根包
     * @param controllerName controller层包名称
     * @return
     */
    fun getPackageConfig(moduleName: String, parentPackageName: String, controllerName: String): PackageConfig {
        // 包配置
        val pc = PackageConfig()
        pc.moduleName = moduleName
        pc.parent = parentPackageName
        pc.controller = controllerName// 这里是控制器包名，默认 web
        pc.entity = "model"
        return pc
    }

    /**
     * 设置项目mapper xml 生成路径
     * @return
     */
    fun getInjectionConfig(): InjectionConfig {
        // 注入自定义配置，可以在 VM 中使用 cfg.abc 设置的值
        val cfg = object : InjectionConfig() {
            override fun initMap() {
                val map = HashMap<String, Any>()
                map["abc"] = this.config.globalConfig.author + "-mp"
                this.map = map
            }
        }
        cfg.fileOutConfigList = Arrays.asList<FileOutConfig>(object : FileOutConfig("/templates/mapper.xml.vm") {

            // 自定义输出文件目录
            override fun outputFile(tableInfo: TableInfo): String {
                val tempPath = outDir!!.replace("kotlin", "resources")

                return tempPath + "/mapper/" + tableInfo.entityName + "Mapper.xml"
            }
        })
        return cfg
    }

    /**
     * 设置生成器自动配置
     * @param dataSourceConfig 数据源配置
     * @param strategyConfig 生成策略配置
     * @param packageConfig 项目包配置
     * @param injectionConfig 生成xml配置
     * @return
     */
    fun getAutoGenerator(
        dataSourceConfig: DataSourceConfig,
        strategyConfig: StrategyConfig,
        packageConfig: PackageConfig,
        injectionConfig: InjectionConfig
    ): AutoGenerator {
        val mpg = AutoGenerator()

        mpg.globalConfig = this.getGlobalConfig()
        mpg.dataSource = dataSourceConfig
        mpg.strategy = strategyConfig
        mpg.packageInfo = packageConfig
        mpg.cfg = injectionConfig

        val tc = TemplateConfig()
        tc.xml = null
        mpg.template = tc
        return mpg
    }


    /**
     * 示例生成
     * 需要用的时候把main1改为main，不要将main上传
     * @param args
     */
}

fun main11(args: Array<String>) {
    val baseAutoGenerator = CodeGen()

    baseAutoGenerator.setAuthor("Gyb").setOutDir(null)

    val url =
        "jdbc:mysql://192.168.10.46:10151/bt-dangjian?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true"
    val dataSourceConfig =
        baseAutoGenerator.getDataSourceConfig(DbType.MYSQL, "com.mysql.jdbc.Driver", "root", "YunJing168", url)

    val strategyConfig =
        baseAutoGenerator.getStrategyConfig(
            arrayOf("bt_"),
            arrayOf("bt_red_party_building"),
            null
        )

    val packageConfig = baseAutoGenerator.getPackageConfig("", "cc.vv.party", "api")

    val injectionConfig = baseAutoGenerator.getInjectionConfig()

    // 执行生成
    val autoGenerator =
        baseAutoGenerator.getAutoGenerator(dataSourceConfig, strategyConfig, packageConfig, injectionConfig)
    autoGenerator.execute()
}

fun main123(args: Array<String>) {
    println(UUID.randomUUID().toString().replace("-", ""))
}

fun main222(args: Array<String>) {
    val json = "{\n" +
            "        \"unreadMsgCount\": 92,\n" +
            "        \"SESSIONID\": \"bc5a71c2-4168-46d8-9d3d-0a67527e6150\",\n" +
            "        \"level\": \"A\",\n" +
            "        \"curSource\": \"APP\",\n" +
            "        \"curPartyMember\": {\n" +
            "            \"partyDues\": 1,\n" +
            "            \"countyRegion\": {\n" +
            "                \"level\": \"rld\",\n" +
            "                \"showCreateTime\": \"2018-06-29 11:41:29\",\n" +
            "                \"name\": \"宝塔区\",\n" +
            "                \"id\": \"610602\",\n" +
            "                \"sort\": 1\n" +
            "            },\n" +
            "            \"education\": \"YJS\",\n" +
            "            \"occupation\": \"other\",\n" +
            "            \"nation\": \"HAN\",\n" +
            "            \"photoPath\": \"/files/image/person/20171030/635cb070297c4ed681518f7fafc80888/c7094b79cc60403d8124bfab28a8b7fe.jpg\",\n" +
            "            \"dist\": \"宝塔区\",\n" +
            "            \"isOnlineStatics\": \"Y\",\n" +
            "            \"roleDispayName\": \"党员\",\n" +
            "            \"province\": \"陕西\",\n" +
            "            \"academicDegree\": \"master\",\n" +
            "            \"isManager\": \"N\",\n" +
            "            \"punishType\": \"W\",\n" +
            "            \"id\": \"635cb070297c4ed681518f7fafc80888\",\n" +
            "            \"isShuji\": \"N\",\n" +
            "            \"isJoinGroup\": \"N\",\n" +
            "            \"nonPublicItem\": \"FGGL\",\n" +
            "            \"roleNum\": 11,\n" +
            "            \"workUnit\": \"无\",\n" +
            "            \"homeplaceProvince\": \"陕西\",\n" +
            "            \"homeplaceDist\": \"宝塔区\",\n" +
            "            \"showJoinPartyDate\": \"2012-10-30\",\n" +
            "            \"starCount\": 3,\n" +
            "            \"phone\": \"13072996151\",\n" +
            "            \"name\": \"葛润菁\",\n" +
            "            \"cityRegion\": {\n" +
            "                \"level\": \"rlc\",\n" +
            "                \"showCreateTime\": \"2018-06-29 11:41:29\",\n" +
            "                \"name\": \"延安市\",\n" +
            "                \"id\": \"610600\",\n" +
            "                \"sort\": 0\n" +
            "            },\n" +
            "            \"city\": \"延安\",\n" +
            "            \"showBecomeDate\": \"2013-10-30\",\n" +
            "            \"isPoor\": \"N\",\n" +
            "            \"beforeBranchName\": \"陕西省西安长安大学党委\",\n" +
            "            \"showJoinBranchDate\": \"2016-03-23\",\n" +
            "            \"showPartyDuesEndDate\": \"2018-11\",\n" +
            "            \"isFlow\": \"N\",\n" +
            "            \"isNonPublic\": \"N\",\n" +
            "            \"displayBirthday\": \"1990-06-29\",\n" +
            "            \"partyBranch\": {\n" +
            "                \"branchIdsChain\": \"8a4da0865c791e3d015c7c357cd837cf\",\n" +
            "                \"address\": \"大砭沟立博小学沟内\",\n" +
            "                \"myPartyCommitteeLayer\": 0,\n" +
            "                \"showCreateTime\": \"2017-06-06 15:01:39\",\n" +
            "                \"groupId\": \"gg801912782901\",\n" +
            "                \"type\": \"COMMUNITY\",\n" +
            "                \"myPartyTotalBranchId\": \"8a4da0865c791e3d015c7c29eec03345\",\n" +
            "                \"myPartyWorkCommitId\": \"8a4da0865c63b402015c725c52f401aa\",\n" +
            "                \"phone\": \"0911-2380440\",\n" +
            "                \"name\": \"凤凰山街道北苑社区第一网格党支部\",\n" +
            "                \"partyTotalBranch\": {\n" +
            "                    \"partyWorkCommit\": {\n" +
            "                        \"showCreateTime\": \"2017-06-04 17:07:52\",\n" +
            "                        \"name\": \"宝塔区凤凰山街道党工委\",\n" +
            "                        \"id\": \"8a4da0865c63b402015c725c52f401aa\"\n" +
            "                    },\n" +
            "                    \"address\": \"宝塔区立博小学巷内\",\n" +
            "                    \"phone\": \"0911-2380440\",\n" +
            "                    \"showCreateTime\": \"2017-06-06 14:49:01\",\n" +
            "                    \"name\": \"凤凰山街道北苑社区党总支\",\n" +
            "                    \"id\": \"8a4da0865c791e3d015c7c29eec03345\"\n" +
            "                },\n" +
            "                \"id\": \"8a4da0865c791e3d015c7c357cd837cf\"\n" +
            "            },\n" +
            "            \"address\": \"畜牧站家属楼2单元\",\n" +
            "            \"monthPraiseCount\": 0,\n" +
            "            \"showCreateTime\": \"2017-10-30 10:38:18\",\n" +
            "            \"sex\": \"m\",\n" +
            "            \"isPunish\": \"N\",\n" +
            "            \"wages\": 0,\n" +
            "            \"stage\": \"regular\",\n" +
            "            \"administrationPost\": \"-1\",\n" +
            "            \"homeplaceCity\": \"延安\",\n" +
            "            \"idcard\": \"610602199006290337\",\n" +
            "            \"isPraise\": \"N\",\n" +
            "            \"isTransferBranch\": \"N\",\n" +
            "            \"totalPraiseCount\": 1,\n" +
            "            \"age\": 28\n" +
            "        },\n" +
            "        \"topLayerPartyWorkCommitteeId\": \"8a4da0865c63b402015c725c52f401aa\",\n" +
            "        \"resourceCtx\": \"http://dja.yadj.gov.cn/pmc\",\n" +
            "        \"unreadTaskCount\": 69,\n" +
            "        \"curRoleId\": \"RMN\",\n" +
            "        \"learningProfile\": {\n" +
            "            \"todayHours\": 0,\n" +
            "            \"hourAndMinute\": \"5小时13分钟\",\n" +
            "            \"showBeginTime\": \"2017-10-31\",\n" +
            "            \"id\": \"ff8080815f6dd2b8015f7091eb7f3111\",\n" +
            "            \"showEndTime\": \"2018-11-22\"\n" +
            "        },\n" +
            "        \"transPartyWorkCommit\": {\n" +
            "            \"showCreateTime\": \"2017-06-04 17:07:52\",\n" +
            "            \"name\": \"宝塔区凤凰山街道党工委\",\n" +
            "            \"id\": \"8a4da0865c63b402015c725c52f401aa\"\n" +
            "        },\n" +
            "        \"rank\": 27252\n" +
            "}"
    val result = json.toJSONObject<MutableMap<String, Any?>>()
    val partyCommitteeId: String? = result.jsonPath("$.curPartyMember.partyBranch..partyCommittee[0].id")
    val partyCommitteeName: String? = result.jsonPath("$.curPartyMember.partyBranch..partyCommittee[0].name")
    val partyWorkCommitteeId: String? = result.jsonPath("$.curPartyMember.partyBranch..partyWorkCommit[0].id")
    val partyWorkCommitteeName: String? = result.jsonPath("$.curPartyMember.partyBranch..partyWorkCommit[0].name")
    val partyTotalBranchId: String? = result.jsonPath("$.curPartyMember.partyBranch..partyTotalBranch[0].id")
    val partyTotalBranchName: String? = result.jsonPath("$.curPartyMember.partyBranch..partyTotalBranch[0].name")
    val partyBranchId: String? = result.jsonPath("$.curPartyMember.partyBranch.id")
    val partyBranchName: String? = result.jsonPath("$.curPartyMember.partyBranch.name")
    val orgMinistryId: String? = result.jsonPath("$.curPartyMember.orgMinistry.id")
    val orgMinistryName: String? = result.jsonPath("$.curPartyMember.orgMinistry.name")


}